package maConfigration;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;


import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class ReadXMLConfig 
{
	Document _doc;
	
	/* Create a global document that the methods will use when getting the information from the
	 * xml file (the document is the xml file)*/
	public ReadXMLConfig()
	{
		try
		{
			//collect config-file and create a "document" from it that is readable
			File file = new File(".\\MainConfigFile.xml");
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			_doc = db.parse(file);
			_doc.getDocumentElement().normalize();
			
		}	
		catch(Exception e)
		{
			System.out.println("Problems when loading the configure file");
			System.out.print(e.getMessage());
		}	
	}	
	
	public Collection<String> getProjectsToBeRun()
	{
		Collection<String> coll = new ArrayList<String>();
		NodeList nl = _doc.getElementsByTagName("projectToRun");
		for(int i = 0; i < nl.getLength(); i++)
		{
			if(nl.item(i).getNodeType() == Node.ELEMENT_NODE)
				coll.add(nl.item(i).getTextContent());
		}
		
		return coll;
	}
	
	/* Get which projects/packages/classes/operations/attributes/Statecharts that should
	 * be excluded from the metric collection */
	public Collection<String> getFilter(String str){
		Collection<String> coll = new ArrayList<String>();
		NodeList nl = _doc.getElementsByTagName(str);
		for(int i = 0; i < nl.getLength(); i++)
		{
			if(nl.item(i).getNodeType() == Node.ELEMENT_NODE)
				coll.add(nl.item(i).getTextContent());
		}
		return coll;
	}
	
	/* Get settings for one metric
	 * return an instance of MetricSettings
	 * */
	public MetricSettings getMetricSettings(String str)
	{
		boolean isProj = false, isPkg = false, isCls = false, isOp = false, isLog = false;
		int nRed = 0, nYellow = 0, nGreen = 0, nToplist = 0;
		float fWRed = 0, fWYellow = 0, fWGreen = 0;
		
		ArrayList<String> results = getMetricConfig(str);
		if(results.size() < 12) return null;
		
		nGreen = Integer.parseInt(results.get(0));
		nYellow = Integer.parseInt(results.get(1));
		nRed = Integer.parseInt(results.get(2));
		//nWGreen = Integer.parseInt(results.get(3));
		//Float.valueOf(s.trim()).floatValue()
		fWGreen = Float.valueOf(results.get(3).trim()).floatValue();
		fWYellow = Float.valueOf(results.get(4).trim()).floatValue();
		fWRed = Float.valueOf(results.get(5).trim()).floatValue();
		nToplist = Integer.parseInt(results.get(6));
		isProj = (results.get(7).equals("1"));
		isPkg = (results.get(8).equals("1"));
		isCls = (results.get(9).equals("1"));
		isOp = (results.get(10).equals("1"));
		isLog = (results.get(11).equals("1"));
		
		MetricSettings ms = new MetricSettings( isProj, isPkg, isCls, isOp, isLog,
			 nRed, nYellow, nGreen, nToplist, fWRed, fWYellow, fWGreen, str);
		return ms;
		
	}
	
	
	//This function get threshold and other configurations for specific metrics
	//getMetricConfig takes a 	String (metric name) 
	//returns back a 			collection {greenThreshold, yellowThreshold, redThreshold, 
	//								greenWeight, yellowWeight, redWeight, nrShowedInTopList
	//								isApplyToProj, isApplyToPkg, isApplyToCls, isApplyToOp}
	public ArrayList<String> getMetricConfig(String str)
	{
		ArrayList<String> coll = new ArrayList<String>();
		NodeList nl = _doc.getElementsByTagName(str);
		for(int i = 0; i < nl.getLength(); i++)
		{
			Node nd = nl.item(i);
			if(nd.getNodeType() == Node.ELEMENT_NODE)
			{
				Element fstElmnt = (Element) nd;
				NodeList fstNmElmntLst = fstElmnt.getElementsByTagName("greenThreshold");
				coll.add(((Node) fstNmElmntLst.item(0)).getTextContent());
				fstNmElmntLst = fstElmnt.getElementsByTagName("yellowThreshold");
				coll.add(((Node) fstNmElmntLst.item(0)).getTextContent());
				fstNmElmntLst = fstElmnt.getElementsByTagName("redThreshold");
				coll.add(((Node) fstNmElmntLst.item(0)).getTextContent());

				fstNmElmntLst = fstElmnt.getElementsByTagName("costToFixGreen");
				coll.add(((Node) fstNmElmntLst.item(0)).getTextContent());
				fstNmElmntLst = fstElmnt.getElementsByTagName("costToFixYellow");
				coll.add(((Node) fstNmElmntLst.item(0)).getTextContent());
				fstNmElmntLst = fstElmnt.getElementsByTagName("costToFixRed");
				coll.add(((Node) fstNmElmntLst.item(0)).getTextContent());
				
				fstNmElmntLst = fstElmnt.getElementsByTagName("nrToplistThreshold");
				coll.add(((Node) fstNmElmntLst.item(0)).getTextContent());

				fstNmElmntLst = fstElmnt.getElementsByTagName("isApplyToProj");
				coll.add(((Node) fstNmElmntLst.item(0)).getTextContent());
				fstNmElmntLst = fstElmnt.getElementsByTagName("isApplyToPkg");
				coll.add(((Node) fstNmElmntLst.item(0)).getTextContent());
				fstNmElmntLst = fstElmnt.getElementsByTagName("isApplyToCls");
				coll.add(((Node) fstNmElmntLst.item(0)).getTextContent());
				fstNmElmntLst = fstElmnt.getElementsByTagName("isApplyToOp");
				coll.add(((Node) fstNmElmntLst.item(0)).getTextContent());
				fstNmElmntLst = fstElmnt.getElementsByTagName("isLogRawData");
				coll.add(((Node) fstNmElmntLst.item(0)).getTextContent());
			}
		}
		return coll;
	}
	
	
	/* Gets which classes that should be applied to the different levels
	 * of the project from the xml file*/
	public Collection<String> isAppliedTo(String str){
		Collection<String> coll = new ArrayList<String>();
		NodeList nl = _doc.getElementsByTagName(str);
		for(int i = 0; i < nl.getLength(); i++)
		{
			if(nl.item(i).getNodeType() == Node.ELEMENT_NODE)
			{
				Element ele = (Element) nl.item(i);
				NodeList values = ele.getElementsByTagName("metric");
				for(int j = 0; j < values.getLength(); j++)
				{
					if(values.item(j).getNodeType() == Node.ELEMENT_NODE)
						coll.add(values.item(j).getTextContent());
				}
			}
		}
		return coll;
	}
}
